package com.briup.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.briup.common.response.ResultCode;
import com.briup.common.utils.AssertUtil;
import com.briup.common.utils.BeanUtil;
import com.briup.server.domain.bean.Device;
import com.briup.server.domain.bean.DeviceType;
import com.briup.server.domain.bean.Labs;
import com.briup.server.domain.dto.DeviceModifiedDTO;
import com.briup.server.domain.dto.DeviceQueryDTO;
import com.briup.server.domain.vo.DeviceDetailVO;
import com.briup.server.mapper.DeviceMapper;
import com.briup.server.service.DeviceService;
import com.briup.server.service.DeviceTypeService;
import com.briup.server.service.LabsService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

@Service
@RequiredArgsConstructor
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService {

    private final LabsService labsService;
    private final DeviceTypeService deviceTypeService;

    @Override
    public Page<DeviceDetailVO> queryDevices(DeviceQueryDTO queryDTO) {
        // 分页查询设备信息
        Page<Device> page = new Page<>(queryDTO.getPage(), queryDTO.getSize());
        // 构建查询条件
        LambdaQueryWrapper<Device> wrapper = Wrappers.<Device>lambdaQuery()
                // 实验室ID不为空时，根据实验室ID查询；即查询该实验室下的所有设备
                .eq(StringUtils.hasText(queryDTO.getLabsId()), Device::getLabsId, queryDTO.getLabsId())
                // 设备类型ID不为空时，根据设备类型ID查询；即查询该设备类型下的所有设备
                .eq(StringUtils.hasText(queryDTO.getDeviceTypeId()), Device::getDeviceType, queryDTO.getDeviceTypeId())
                // 设备名称不为空时，根据设备名称查询；即查询设备名称包含该字符串的所有设备
                .like(StringUtils.hasText(queryDTO.getDeviceName()), Device::getDeviceName, queryDTO.getDeviceName());
        // 执行查询
        page(page, wrapper);
        // 转换为VO对象
        Page<DeviceDetailVO> detailVOPage = convertToDetailVO(page);
        detailVOPage.setTotal(count(wrapper));
        // 返回查询结果
        return detailVOPage;
    }

    @Override
    public void saveOrUpdateDevice(DeviceModifiedDTO modifiedDTO) {
        // 检查设备是否存在
        checkDeviceExist(modifiedDTO);
        // 转换为实体对象
        Device device = BeanUtil.convert(modifiedDTO, Device.class, "typeId");
        device.setDeviceType(modifiedDTO.getTypeId());

        // 保存或更新设备信息
        saveOrUpdate(device);
    }

    /**
     * 检查设备是否存在
     *
     * @param modifiedDTO 设备新增或修改数据DTO实体
     */
    private void checkDeviceExist(DeviceModifiedDTO modifiedDTO) {
        // 当设备ID不为空时（即修改设备信息），检查设备是否存在
        if (StringUtils.hasText(modifiedDTO.getId())) {
            Device device = getById(modifiedDTO.getId());
            AssertUtil.notNull(device, ResultCode.DEVICE_IS_NOT_EXISTS);
        }
        // 确保名字是唯一的
        LambdaQueryWrapper<Device> wrapper = Wrappers.<Device>lambdaQuery().eq(Device::getDeviceName, modifiedDTO.getDeviceName()).ne(StringUtils.hasText(modifiedDTO.getId()), Device::getId, modifiedDTO.getId());
        // 检查是否存在相同名称的设备
        AssertUtil.isTrue(count(wrapper) == 0, ResultCode.DEVICE_NAME_EXISTS);

        // 确保实验室ID存在
        Labs labs = labsService.getById(modifiedDTO.getLabsId());
        AssertUtil.notNull(labs, ResultCode.LABS_IS_NOT_EXISTS);
        // 确保设备类型ID存在
        DeviceType deviceType = deviceTypeService.getById(modifiedDTO.getTypeId());
        AssertUtil.notNull(deviceType, ResultCode.DEVICE_TYPE_IS_NOT_EXISTS);
    }

    private Page<DeviceDetailVO> convertToDetailVO(Page<Device> page) {
        // 创建新的VO对象，用于存储转换后的结果
        Page<DeviceDetailVO> detailVOPage = new Page<>(page.getCurrent(), page.getSize());
        List<Device> records = page.getRecords();
        // 转换为VO对象
        List<DeviceDetailVO> list = records.stream().map(device -> {
            DeviceDetailVO detailVO = BeanUtil.convert(device, DeviceDetailVO.class);
            // 设置实验室名称，为了保证程序的安全性，
            // 当实验室ID为空时，不设置实验室名称
            if (StringUtils.hasText(device.getLabsId())) {
                detailVO.setLabsName(labsService.getById(device.getLabsId()).getLabsName());
            }
            // 设置设备类型名称，为了保证程序的安全性，
            // 当设备类型ID为空时，不设置设备类型名称
            if (StringUtils.hasText(device.getDeviceType())) {
                detailVO.setDeviceTypeName(deviceTypeService.getById(device.getDeviceType()).getTypeName());
            }
            return detailVO;
        }).toList();
        // 设置VO对象的记录列表
        detailVOPage.setRecords(list
                .stream().skip((page.getCurrent() - 1) * page.getSize())
                .limit(page.getSize())
                .toList());
        return detailVOPage;
    }
}




